<template>
	<view :class="maxCount>1?'upload upload_max':'upload'">
		<uv-upload ref="uvUpload" :uploadText="uploadText" :id="'my-drag-files'+name" :name="String(name)"
			:accept="accept" :capture="capture" class="uv_upload" :fileList="fileList" :multiple="maxCount>1?true:false"
			:maxCount="maxCount" @afterRead="afterRead" @delete="deletePic" :previewFullImage="true" :width="viewWidth"
			:height="viewHeight" :imageMode="mode" :deletable="deletable">
		</uv-upload>
		<uv-toast ref="toast"></uv-toast>
		<helang-compress ref="helangCompress"></helang-compress>
	</view>
</template>

<script>
	import config from '@/common/config'
	import {
		uploadFile
	} from '@/common/api.js';
	import helangCompress from '@/components/compress/compress.vue';
	export default {
		components: {
			// 注册组件
			helangCompress
		},
		props: {
			fileList: {
				type: Array,
				default: []
			},
			accept: {
				type: String,
				default: 'image'
			},
			compressType: {
				type: String,
				default: null
			},
			url: {
				type: String,
				default: 'image'
			},
			mode: {
				type: String,
				default: 'widthFix'
			},
			uploadText: {
				type: String,
				default: ''
			},
			compress: {
				type: Number, //kb
				default: 1024
			},
			maxSize: {
				type: [Number, String],
				default: 3 * 1024 * 1024
			},
			minWidth: {
				type: [Number, String],
				default: 1
			},
			maxCount: {
				type: [Number, String],
				default: '1'
			},
			name: {
				type: [Number, String],
				default: '1'
			},
			height: {
				type: [Number, String],
				default: 0
			},
			width: {
				type: [Number, String],
				default: 0
			},
			deletable: {
				type: Boolean,
				default: true
			},
		},
		data() {
			return {
				viewWidth: this.height,
				viewHeight: this.width,
				obj: {},
				capture: ['album', 'camera'],
				type: '',
				resdata: [],
				afterIndex: 0,
			}
		},
		computed: {
			allowedTypes() {
				if (this.accept == 'media') {
					return ['mp3', 'wav', 'mp4', 'avi', 'mov'];
				}
				if (this.accept == 'image') {
					return ["image", "png", "jpeg", "jpg", "gif", "webp", "svg", 'bmp'];
				}
				if (this.accept == 'file') {
					return ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt'];
				}
				if (this.accept == 'video') {
					return ['mp4', 'webm', 'ogg', 'mov', 'avi', 'mkv'];
				}
				if (this.accept == 'all') {
					return ['mp4', 'webm', 'ogg', 'mov', 'avi', 'mkv'];
				}
				return this.accept.split(',');
			},
		},
		onLoad() {},
		watch: {
			// 监听data数据的变化
			obj(newVal, oldVal) {
				this.$emit('obj', newVal);
			},
			resdata(newVal, oldVal) {
				this.$emit('resdata', newVal);
			},
		},
		mounted() {
			if (!this.height && !this.width) {
				this.getViewSize(true);
			}

			//添加监听
			let elem = document.getElementById('my-drag-files' + this.name);
			elem.addEventListener('drop', this.ondrop, false);
			elem.addEventListener('dragleave', this.ondropprevent);
			elem.addEventListener('dragenter', this.ondropprevent);
			elem.addEventListener('dragover', this.ondropprevent);
			this.elem = elem;
		},
		// 销毁时
		beforeDestroy() {
			const {
				elem
			} = this;
			//移除监听
			elem.removeEventListener('drop', this.ondrop);
			elem.removeEventListener('dragleave', this.ondropprevent);
			elem.removeEventListener('dragenter', this.ondropprevent);
			elem.removeEventListener('dragover', this.ondropprevent);
		},
		beforeUnmount() {
			const {
				elem
			} = this;
			//移除监听
			elem.removeEventListener('drop', this.ondrop);
			elem.removeEventListener('dragleave', this.ondropprevent);
			elem.removeEventListener('dragenter', this.ondropprevent);
			elem.removeEventListener('dragover', this.ondropprevent);
		},
		methods: {
			handleClick() {
				// this.$refs.uvUpload.$refs.previewVideo.open();
				this.$refs.uvUpload.chooseFile();
			},
			ondrop(event) {
				let files = event.dataTransfer.files;
				let list = [];
				for (let i = 0; i < files.length; i++) {
					let url = this.getTempFilePath(files[i]);
					// if (this.maxCount > 1) {

					// } else {
					// 	list = { // thumb: url,
					// 		name: files[i].name,
					// 		size: files[i].size,
					// 		type: files[i].type,
					// 		url: url,
					// 	};
					// }
					list.push({ // thumb: url,
						name: files[i].name,
						size: files[i].size,
						type: files[i].type,
						url: url,
					});
				}
				this.afterRead({
					file: list,
					name: String(this.name),
					index: this.fileList.length
				});
				this.ondropprevent(event);
				return;
			},
			ondropprevent(event) {
				event.stopPropagation();
				event.preventDefault();
			},
			getTempFilePath(file) {
				let path;
				if (window.createObjectURL) path = window.createObjectURL(file);
				else if (window.webkitURL) path = window.webkitURL.createObjectURL(file);
				else if (window.URL) path = window.URL.createObjectURL(file);
				else console.error('getTempFilePath has error');
				return path;
			},
			getViewSize(e) {
				var that = this;
				const query = uni.createSelectorQuery().in(this);
				query.select('.uv_upload').boundingClientRect(data => {
					if (data) {
						this.obj = data;
						if (e) {
							that.viewWidth = data.width;
							that.viewHeight = parseInt(that.viewWidth / 1.9);
							this.obj.height = that.viewHeight;
						}
					}
				}).exec();
			},
			// 删除图片
			deletePic(e) {
				this.resdata.splice(e.index, 1);
				this.fileList.splice(e.index, 1);
			},
			deletes(url) {
				for (let y = 0; y < this.fileList.length; y++) {
					if (this.fileList[y].url == url) {
						this.fileList.splice(y, 1);
						return;
					}
				}
			},
			// 新增图片
			async afterRead(event) {
				// console.log(event);
				var that = this;
				this.$emit('focus');
				// 当设置 multiple 为 true 时, file 为数组格式，否则为对象格式
				let lists = [].concat(event.file)
				let fileListLen = this.fileList.length
				lists.map((item) => {
					this.fileList.push({
						...item,
						status: 'uploading',
						message: '上传中'
					})
				})
				for (let i = 0; i < lists.length; i++) {
					if (this.maxCount < this.fileList.length) {
						this.deletes(lists[i].url);
						continue; // 跳过本次循环
					}
					// 获取文件扩展名并验证
					const typeExt = lists[i].type.split('/')[1] || lists[i].type;
					const ext = lists[i].name.split('.').pop().toLowerCase();
					// console.log(typeExt, ext);
					// console.log(this.allowedTypes, this.allowedTypes.some(ele => ele.includes(typeExt)));
					if (this.accept != "all") {
						if (!this.allowedTypes.some(ele => ele.includes(typeExt)) || !this.allowedTypes.some(ele => ele
								.includes(ext))) {
							uni.$uv.toast('请上传 ' + this.allowedTypes.join("/") + ' 格式文件');
							this.deletes(lists[i].url);
							continue; // 非法文件类型处理，跳过本次循环
						}
					}

					// console.log(lists[i].size, this.compress * 1024, lists[i].size > this.compress *
					// 	1024);
					if (Number(lists[i].size) > Number(this.maxSize)) {
						uni.$uv.toast('文件大小超过限制' + this.maxSize / 1024 / 1024 + 'M');
						this.deletes(lists[i].url);
						continue;
					}
					let image = lists[i].url,
						images = '';
					images = await that.imageInfoPromise(lists[i].url);
					if (images) {
						this.type = 'image';
						if (Number(images.width) < Number(this.minWidth)) {
							uni.$uv.toast('图片尺寸不小于' + this.minWidth + 'px');
							this.deletes(lists[i].url);
							continue;
						}
						if (lists[i].size > this.compress * 1024) {
							// 图片压缩 images.width > 2048 ? 2048 : images.width,
							try {
								image = await that.$refs.helangCompress.compressFun({
									src: lists[i].url,
									maxSize: images.width > 1920 ? 1920 : images.width,
									// fileType: lists[i].name.split('.').pop(),
									fileType: 'png',
									quality: 0.85,
									resType: 'image',
									minSize: 640 //最小压缩尺寸，图片尺寸小于该时值不压缩，非H5平台有效。若需要忽略该设置，可设置为一个极小的值，比如负数。
								});
							} catch (e) {
								console.error('catch', e);
							}
						}
					} else {
						this.type = 'file';
					}

					const data = await this.uploadFilePromise(image)
					if (data.url) {
						let item = this.fileList[fileListLen]
						this.fileList.splice(fileListLen, 1, Object.assign(item, {
							status: 'success',
							message: '',
							url: data.url,
							path: data.path,
							base64: 'data:' + data.mimetype + ';base64,' + data.baseimg,
							baseimg: data.baseimg
						}))

						let ites = this.resdata[fileListLen] || {};
						this.resdata.splice(fileListLen, 1, Object.assign(ites, {
							url: data.url,
							path: data.path,
							base64: 'data:' + data.mimetype + ';base64,' + data.baseimg,
							baseimg: data.baseimg
						}))
						fileListLen++
					}
				}
			},
			uploadFilePromise(url) {
				var that = this;
				return new Promise((resolve, reject) => {
					uploadFile(this.url, {
						custom: {
							auth: true,
							catch: true
						},
						name: this.url,
						filePath: url,
						formData: {
							type: that.type,
							compressType: that.compressType
						},
					}).then(res => {
						setTimeout(() => {
							resolve(res)
						}, 1000)
					}).catch(e => {
						console.error(e);
						this.fileList.splice(event.index, 1)
					})
				})
			},
			imageInfoPromise(url) {
				var that = this;
				return new Promise((resolve, reject) => {
					uni.getImageInfo({
						src: url,
						success: function(images) {
							resolve(images)
						},
						fail: function(err) {
							console.error('err', err);
							resolve(null);
						},
					});
				})
			}
		}
	}
</script>

<style scoped lang="scss">
	.upload {
		margin: 0px;
		display: flex;
		justify-content: center;
		align-items: center;
		width: 100%;

		.uv_upload {
			width: 100%;
			border: 1px;
			border-color: #ffaaff;
			border-style: solid;
			overflow: hidden;

			::v-deep .uv-upload__wrap__preview {
				margin: 0px;
			}

			::v-deep .uv-upload__button {
				margin: 0px;
			}

			::v-deep .uv-upload__deletable {
				height: 25px;
				width: 25px;
				cursor: pointer;
			}

			::v-deep .uv-upload__deletable__icon {
				top: 5px;
				right: 5px
			}

			::v-deep .uv-upload__success {
				bottom: 0px;
				right: 2px;
			}

			::v-deep .uv-upload__deletable {
				z-index: 0;
			}
		}
	}

	.upload_max {
		display: flex;
		justify-content: center;
		align-items: center;

		.uv_upload {
			border: 0px;
			margin-bottom: 5px;

			::v-deep .uv-upload__wrap {
				margin-right: 10px;
				display: flex;
				flex-direction: row;
				flex-wrap: wrap;
				flex: 1;
			}

			::v-deep .uv-upload__wrap__preview {
				margin-right: 10px;
				border-radius: 6px;
				margin-bottom: 6px;
			}
		}
	}
</style>